=begin pod :kind("Type") :subkind("class") :category("composite")

=TITLE class List

=SUBTITLE Sequence of values

=for code
my class List does Iterable does Positional { }

C<List> stores items sequentially and potentially lazily.

Indexes into lists and arrays start at 0 by default.

You can assign to list elements if they are containers. Use
Arrays to have every value of the list stored in a container.

C<List> implements C<Positional> and as such provides support for
L<subscripts|/language/subscripts>.

=head1 Immutability

Lists are immutable objects, i.e., neither the number of elements in a list
nor the elements themselves can be changed. Thus, it is not possible to use
operations that change the list structure itself such as L<shift|/routine/shift>,
L<unshift|/routine/unshift>, L<push|/routine/push>, L<pop|/routine/pop>,
L<splice|/routine/splice>
and L<binding|/language/operators#index-entry-Binding_operator>.

=begin code :skip-test<illustrates error>
(1, 2, 3).shift;      # Error Cannot call 'shift' on an immutable 'List'
(1, 2, 3).unshift(0); # Error Cannot call 'unshift' on an immutable 'List'
(1, 2, 3).push(4);    # Error Cannot call 'push' on an immutable 'List'
(1, 2, 3).pop;        # Error Cannot call 'pop' on an immutable 'List'
(1, 2, 3)[0]:delete;  # Error Cannot remove elements from a List
(1, 2, 3)[0] := 0;    # Error Cannot use bind operator with this left-hand side
(1, 2, 3)[0] = 0;     # Error Cannot modify an immutable Int
=end code

A C«List» doesn't L«containerize|/language/containers» its elements, but if
any element happens to be inside a L«Scalar|/type/Scalar» container then
the element's contents can be replaced via an assignment.

=begin code :skip-test<illustrates error>
my $a = 'z';
my $list = ($a, $, 'b');

say $list[0].VAR.^name; # OUTPUT: «Scalar␤», containerized
say $list[1].VAR.^name; # OUTPUT: «Scalar␤», containerized
say $list[2].VAR.^name; # OUTPUT: «Str␤», non-containerized

$list[0] = 'a'; # OK!
$list[1] = 'c'; # OK!
$list[2] = 'd'; # Error: Cannot modify an immutable List
=end code

=head1 Items, flattening and sigils

In Raku, assigning a C<List> to a scalar variable does not lose information.
The difference is that iteration generally treats a list (or any other list-like
object, like a L<Seq|/type/Seq> or an L<Array|/type/Array>) inside a scalar as a
single element.

    my $s = (1, 2, 3);
    for $s { }      # one iteration
    for $s.list { } # three iterations

    my $t = [1, 2, 3];
    for $t { }      # one iteration
    for $t.list { } # three iterations

    my @a = 1, 2, 3;
    for @a { }      # three iterations
    for @a.item { } # one iteration

This operation is called I<itemization> or I<putting in an item context>.
C<.item> does the job for objects, as well as C<$( ... )> and, on array
variables, C<$@a>.

Lists generally don't interpolate (flatten) into other lists, except
when they are in list context and the single argument to an
operation such as C<append>:

    my $a = (1, 2, 3);
    my $nested = ($a, $a);  # two elements

    my $flat = $nested.map({ .Slip });  # six elements, with explicit Slip

    my @b = <a b>;
    @b.append: $a.list;     # The array variable @b has 5 elements, because
                            # the list $a is the sole argument to append

    say @b.elems;           # OUTPUT: «5␤»

    my @c = <a b>;
    @c.append: $a.list, 7;  # The array variable @c has 4 elements, because
                            # the list $a wasn't the only argument and thus
                            # wasn't flatten by the append operation

    say @c.elems;           # OUTPUT: «4␤»

    my @d = <a b>;
    @d.append: $a;          # The array variable @d has 3 elements, because
                            # $a is in an item context and as far as append is
                            # concerned a single element

    say @d.elems;           # OUTPUT: «3␤»

The same flattening behavior applies all objects that do the
L<Iterable|/type/Iterable> role, notably L<hashes|/type/Hash>:

    my %h = a => 1, b => 2;
    my @b = %h;   say @b.elems;     # OUTPUT: «2␤»
    my @c = %h, ; say @c.elems;     # OUTPUT: «1␤»
    my @d = $%h;  say @d.elems;     # OUTPUT: «1␤»

Slurpy parameters (C<*@a>) flatten non-itemized sublists:

    sub fe(*@flat) { @flat.elems }
    say fe(<a b>, <d e>);           # OUTPUT: «4␤»
    say fe(<a b>, <d e>.item);      # OUTPUT: «3␤»

X<|(),empty list>
The empty list is created with C<()>. Smartmatching against the empty
list will check for the absence of elements.

    my @a;
    for @a, @a.list, @a.Seq -> \listoid {
        say listoid ~~ ()
    }
    # OUTPUT: «True␤True␤True␤»

Retrieving values from an empty list will always return C<Nil>:

    say ()[33.rand]; # OUTPUT: «Nil␤»


Coercion to C<Bool> also indicates if the C<List> got any elements.

    my @a;
    say [@a.elems, @a.Bool, ?@a]; # OUTPUT: «[0 False False]␤»
    @a.push: 42;
    say [@a.elems, @a.Bool, ?@a]; # OUTPUT: «[1 True True]␤»
    say 'empty' unless @a;        # no output

=head1 Methods

=head2 method ACCEPTS

Defined as:

    multi method ACCEPTS(List:D: $topic)

If C<$topic> is an L<Iterable|/type/Iterable>, returns C<True> or C<False> based
on whether the contents of the two C<Iterables> match. A
L<Whatever|/type/Whatever> element in the invocant matches anything in the
corresponding position of the C<$topic> C<Iterable>. A
L<HyperWhatever|/type/HyperWhatever> matches any number of any elements,
including no elements:

    say (1, 2, 3)       ~~ (1,  *, 3);  # OUTPUT: «True␤»
    say (1, 2, 3)       ~~ (9,  *, 5);  # OUTPUT: «False␤»
    say (1, 2, 3)       ~~ (   **, 3);  # OUTPUT: «True␤»
    say (1, 2, 3)       ~~ (   **, 5);  # OUTPUT: «False␤»
    say (1, 3)          ~~ (1, **, 3); # OUTPUT: «True␤»
    say (1, 2, 4, 5, 3) ~~ (1, **, 3); # OUTPUT: «True␤»
    say (1, 2, 4, 5, 6) ~~ (1, **, 5); # OUTPUT: «False␤»
    say (1, 2, 4, 5, 6) ~~ (   **   ); # OUTPUT: «True␤»
    say ()              ~~ (   **   ); # OUTPUT: «True␤»

In addition, returns C<False> if either the invocant or C<$topic>
L<is a lazy|/routine/is-lazy> C<Iterable>, unless C<$topic> is the same object
as the invocant, in which case C<True> is returned.

If C<$topic> is I<not> an L<Iterable|/type/Iterable>, returns the invocant if
the invocant has no elements or its first element is a L<Match|/type/Match>
object (this behavior powers C<m:g//> smartmatch), or C<False> otherwise.

=head2 routine list

Defined as:

    multi sub    list(+list)
    multi method list(List:D:)

The method just returns the invocant L<self|/routine/self>. The subroutine
adheres to the L<single argument rule|/language/functions#Slurpy_conventions>:
if called with a single argument that is a non-L<itemized|/language/mop#VAR>
C<Iterable> it returns a C<List> based on the argument's
L<iterator|/routine/iterator>; otherwise it just returns the argument list.

For example:

    my $tuple = (1, 2);         # an itemized List
    put $tuple.list.raku;       # OUTPUT: «(1, 2)␤»
    put list($tuple).raku;      # OUTPUT: «($(1, 2),)␤»
    put list(|$tuple).raku;     # OUTPUT: «(1, 2)␤»

The last statement uses the L«C<prefix:<|>>|/language/operators#prefix_|»
operator to flatten the tuple into an argument list, so it is equivalent to:

    put list(1, 2).raku;        # OUTPUT: «(1, 2)␤»

There are other ways to list the elements of an itemized single argument. For
example, you can L«decontainerize|/routine/<>» the argument or use the L<C<@>
list contextualizer|/type/Any#index-entry-@_list_contextualizer>:

=begin code :preamble<my $tuple>
put list($tuple<>).raku;    # OUTPUT: «(1, 2)␤»
put list(@$tuple).raku;     # OUTPUT: «(1, 2)␤»
=end code

Note that converting a type object to a list may not do what you expect:

    put List.list.raku;         # OUTPUT: «(List,)␤»

This is because the C<.list> candidate accepting a type object as the invocant
is provided by L<C<Any>|/routine/list#(Any)_method_list>. That candidate returns
a list with one element: the type object self. If you're developing a collection
type whose type object should be a valid representation of an empty collection,
you may want to provide your own candidate for undefined invocants or override
the C<Any:> candidates with an "only" method. For example:

=begin code
my class LinkedList {
    has $.value;            # the value stored in this node
    has LinkedList $.next;  # undefined if there is no next node

    method values( --> Seq:D) {
        my $node := self;
        gather while $node {
            take $node.value;
            $node := $node.next;
        }
    }

    method list( --> List:D) {
        self.values.list;
    }
}

my LinkedList $nodes;       # an empty linked list
put $nodes.list.raku;       # OUTPUT: «()␤»
=end code

=head2 routine elems

Defined as:

    sub    elems($list --> Int:D)
    method elems(List:D: --> Int:D)

Returns the number of elements in the list.

    say (1,2,3,4).elems; # OUTPUT: «4␤»

=head2 routine end

Defined as:

    sub    end($list --> Int:D)
    method end(List:D: --> Int:D)

Returns the index of the last element.

    say (1,2,3,4).end; # OUTPUT: «3␤»

=head2 routine keys

Defined as:

    sub    keys($list --> Seq:D)
    method keys(List:D: --> Seq:D)

Returns a sequence of indexes into the list (e.g.,
C<0..(@list.elems-1)>).

    say (1,2,3,4).keys; # OUTPUT: «0..3␤»

=head2 routine values

Defined as:

    sub    values($list --> Seq:D)
    method values(List:D: --> Seq:D)

Returns a sequence of the list elements, in order.

    say (1,2,3,4).^name;        # OUTPUT: «List␤»
    say (1,2,3,4).values.^name; # OUTPUT: «Seq␤»

=head2 routine kv

Defined as:

    sub    kv($list --> Seq:D)
    method kv(List:D: --> Seq:D)

Returns an interleaved sequence of indexes and values. For example

    say <a b c>.kv; # OUTPUT: «(0 a 1 b 2 c)␤»

=head2 routine pairs

Defined as:

    sub    pairs($list --> Seq:D)
    method pairs(List:D: --> Seq:D)

Returns a sequence of pairs, with the indexes as keys and the list values as
values.

    say <a b c>.pairs;   # OUTPUT: «(0 => a 1 => b 2 => c)␤»

=head2 routine antipairs

Defined as:

    method antipairs(List:D: --> Seq:D)

Returns a L<Seq|/type/Seq> of pairs, with the values as keys and the indexes as
values, i.e. the direct opposite to L<pairs|/type/List#routine_pairs>.

    say <a b c>.antipairs;  # OUTPUT: «(a => 0 b => 1 c => 2)␤»

=head2 routine invert

Defined as:

    method invert(List:D: --> Seq:D)

Assumes every element of the List is a C<Pair>.  Returns all elements as a
L<Seq|/type/Seq> of C<Pair>s where the keys and values have been exchanged.
If the value of a C<Pair> is an C<Iterable>, then it will expand the values
of that C<Iterable> into separate pairs.

    my $l = List.new('a' => (2, 3), 'b' => 17);
    say $l.invert;   # OUTPUT: «(2 => a 3 => a 17 => b)␤»

=head2 routine join

Defined as:

    sub    join($separator, *@list)
    method join(List:D: $separator = "")

Treats the elements of the list as strings by calling
L<C<.Str>|/type/Mu#method_Str> on each of them, interleaves them with
C<$separator> and concatenates everything into a single string.

Example:

    say join ', ', <a b c>;             # OUTPUT: «a, b, c␤»

The method form also allows you to omit the separator:

    say <a b c>.join;               # OUTPUT: «abc␤»

Note that the method form does not flatten sublists:

    say (1, <a b c>).join('|');     # OUTPUT: «1|a b c␤»

The subroutine form behaves slurpily, flattening all arguments after
the first into a single list:

    say join '|', 1, <a b c>;       # OUTPUT: «1|a|b|c␤»

In this case, the list C«<a b c>» is I<slurped> and flattened, unlike what
happens when C<join> is invoked as a method.

If one of the elements of the list happens to be a C<Junction>, then C<join>
will also return a C<Junction> with concatenation done as much as possible:

    say ("a"|"b","c","d").join;     # OUTPUT: «any(acd,bcd)␤»

=head2 routine map

Defined as:

    multi method map(Hash:D \hash)
    multi method map(Iterable:D \iterable)
    multi method map(|c)
    multi method map(\SELF: &block;; :$label, :$item)
    multi sub map(&code, +values)

Examples applied to lists are included here for the purpose of illustration.

For a list, it invokes C<&code> for each element and gathers the return values
in a sequence and returns it. This happens lazily, i.e. C<&code> is only invoked
when the return values are accessed.Examples:

=for code
say ('hello', 1, 22/7, 42, 'world').map: { .^name } # OUTPUT: «(Str Int Rat Int Str)␤»
say map *.Str.chars, 'hello', 1, 22/7, 42, 'world'; # OUTPUT: «(5 1 8 2 5)␤»

C<map> inspects the arity of the code object, and tries to pass as many
arguments to it as expected:

    sub b($a, $b) { "$a before $b" };
    say <a b x y>.map(&b).join(', ');   # OUTPUT: «a before b, x before y␤»

iterates the list two items at a time.

Note that C<map> does not flatten embedded lists and arrays, so

    ((1, 2), <a b>).map({ .join(',')})

passes C<(1, 2)> and C<< <a b> >> in turn to the block, leading to a total of
two iterations and the result sequence C<"1,2", "a,b">. See
L<method flatmap|/type/List#method_flatmap> for an alternative that flattens.

If C<&code> is a L<Block|/type/Block> loop phasers will be executed and
loop control statements will be treated as in loop control flow. Please
note that C<return> is executed in the context of its definition. It is
not the return statement of the block but the surrounding Routine. Using
a L<Routine|/type/Routine> will also handle loop control statements and
loop phasers. Any C<Routine> specific control statement or phaser will
be handled in the context of that C<Routine>.

    sub s {
        my &loop-block = {
            return # return from sub s
        };
        say 'hi';
        (1..3).map: &loop-block;
        say 'oi‽' # dead code
    };
    s
    # OUTPUT: «hi␤»

=head2 method flatmap

Defined as:

    method flatmap(List:D: &code --> Seq:D)

Like L«C<map>|/type/Any#routine_map» iterates over the elements of the invocant
list, feeding each element in turn to the code reference, and assembling the
return values from these invocations in a result list.

The use of C<flatmap> B<is strongly discouraged>. Instead of C<.flatmap( )>,
please use C<.map( ).flat> as it is clear when the C<.flat> is called
and is not confusing like C<.flatmap>.

Unlike C<map> it flattens non-itemized lists and arrays, so

    ## flatmap
    my @list = ('first1', ('second2', ('third3', 'third4'), 'second5'), 'first6');
    say @list.flatmap({.reverse}).raku;
    # OUTPUT: «("first1", "second5", "third3", "third4", "second2", "first6").Seq␤»
    ## map
    say @list.map({"$_ was a {.^name}"}).raku;
    # OUTPUT: «("first1 was a Str", "second2 third3 third4 second5 was a List", "first6 was a Str").Seq␤»
    ## .map .flat has the same output as .flatmap
    say @list.map({.reverse}).flat.raku;
    # OUTPUT: «("first1", "second5", "third3", "third4", "second2", "first6").Seq␤»

=head2 method gist

Defined as:

    multi method gist(List:D: --> Str:D)

Returns the string containing the parenthesized "gist" of the List,
B<listing up to the first 100> elements, separated by space, appending an
ellipsis if the List has more than 100 elements. If List
L«C<is-lazy>|/routine/is-lazy», returns string C«'(...)'»

=begin code
put (1, 2, 3).gist;   # OUTPUT: «(1 2 3)␤»
put (1..∞).List.gist; # OUTPUT: «(...)␤»

put (1..200).List.gist;
# OUTPUT:
# (1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
# 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
# 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
# 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
# 96 97 98 99 100 ...)
=end code

=head2 routine grep

Defined as:

    sub    grep(Mu $matcher, *@elems, :$k, :$kv, :$p, :$v --> Seq:D)
    method grep(List:D:  Mu $matcher, :$k, :$kv, :$p, :$v --> Seq:D)

Returns a sequence of elements against which C<$matcher> smartmatches.
The elements are returned in the order in which they appear in the original
list.

Examples:

    say ('hello', 1, 22/7, 42, 'world').grep: Int;              # OUTPUT: «(1 42)␤»
    say grep { .Str.chars > 3 }, 'hello', 1, 22/7, 42, 'world'; # OUTPUT: «(hello 3.142857 world)␤»


Note that if you want to grep for elements that do not match, you can
use a C<none>-L<Junction|/type/Junction>:

    say <a b 6 d 8 0>.grep(none Int);           # OUTPUT: «(a b d)␤»
    say <a b c d e f>.grep(none /<[aeiou]>/);   # OUTPUT: «(b c d f)␤»

Another option to grep for elements that do not match a regex is to
use a block:

    say <a b c d e f>.grep({! /<[aeiou]>/})     # OUTPUT: «(b c d f)␤»

The reason the example above works is because a regex in Boolean context applies
itself to C<$_>. In this case, C<!> boolifies the C«/<[aeiou]>/» regex and
negates the result. Smartmatching against a L<Callable|/type/Callable> (in this
case a L<Block|/type/Block>) returns the value returned from that callable, so
the boolified result of a regex is then used to decide whether the current value
should be kept in the result of a grep.

The optional named parameters C<:k>, C<:kv>, C<:p>, C<:v> provide the same
functionality as on slices:

=item k

Only return the index values of the matching elements in order.

=item kv

Return both the index and matched elements in order.

=item p

Return the index and the matched element as a C<Pair>, in order.

=item v

Only return the matched elements (same as not specifying any named parameter
at all).

Examples:

    say ('hello', 1, 22/7, 42, 'world').grep: Int, :k;
    # OUTPUT: «(1 3)␤»
    say grep { .Str.chars > 3 }, :kv, 'hello', 1, 22/7, 42, 'world';
    # OUTPUT: «(0 hello 2 3.142857 4 world)␤»
    say grep { .Str.chars > 3 }, :p, 'hello', 1, 22/7, 42, 'world';
    # OUTPUT: «(0 => hello 2 => 3.142857 4 => world)␤»

=head2 routine first

Defined as:

    sub    first(Mu $matcher, *@elems, :$k, :$kv, :$p, :$end)
    method first(List:D:  Mu $matcher?, :$k, :$kv, :$p, :$end)

Returns the first item of the list which smartmatches against C<$matcher>,
returns C<Nil> when no values match.  The optional named parameter C<:end>
indicates that the search should be from the B<end> of the list, rather than
from the start.

Examples:

    say (1, 22/7, 42, 300).first: * > 5;                  # OUTPUT: «42␤»
    say (1, 22/7, 42, 300).first: * > 5, :end;            # OUTPUT: «300␤»
    say ('hello', 1, 22/7, 42, 'world').first: Complex;   # OUTPUT: «Nil␤»

The optional named parameters C<:k>, C<:kv>, C<:p> provide the same
functionality as on slices:

=item k

Return the index value of the matching element.  Index is always counted from
the beginning of the list, regardless of whether the C<:end> named parameter
is specified or not.

=item kv

Return both the index and matched element.

=item p

Return the index and the matched element as a C<Pair>.

Examples:

    say (1, 22/7, 42, 300).first: * > 5, :k;        # OUTPUT: «2␤»
    say (1, 22/7, 42, 300).first: * > 5, :p;        # OUTPUT: «2 => 42␤»
    say (1, 22/7, 42, 300).first: * > 5, :kv, :end; # OUTPUT: «(3 300)␤»

In method form, the C<$matcher> can be omitted, in which case the first
available item (or last if C<:end> is set) will be returned. See also
L«C<head>|/routine/head» and L«C<tail>|/routine/tail» methods.

=head2 method head

Defined as:

    multi method head(Any:D:) is raw
    multi method head(Any:D: Callable:D $w)
    multi method head(Any:D: $n)

This method is directly inherited from L<Any|/type/Any>, and it returns the B<first> C<$n>
items of the list, an empty list if C<$n> <= 0, or the first element with no
argument. The version that takes a C<Callable> uses a C<WhateverCode> to specify
all elements, starting from the first, but the last ones.

Examples:

    say <a b c d e>.head ;     # OUTPUT: «a␤»
    say <a b c d e>.head(2);   # OUTPUT: «(a b)␤»
    say <a b c d e>.head(*-3); # OUTPUT: «(a b)␤»

=head2 method tail

Defined as:

    multi method tail(List:D:)
    multi method tail(List:D: $n --> Seq:D)

Returns a L<Seq|/type/Seq> containing the B<last> C<$n> items of the list.
Returns an empty C<Seq> if C<$n> <= 0.  Defaults to the last element if
no argument is specified. Throws an exception if the list is lazy.

Examples:

=for code
say <a b c d e>.tail(*-3);# OUTPUT: «(d e)␤»
say <a b c d e>.tail(2);  # OUTPUT: «(d e)␤»
say <a b c d e>.tail;     # OUTPUT: «e␤»

In the first case, C<$n> is taking the shape of a C<WhateverCode> to indicate
the number of elements from the beginning that will be excluded. C<$n> can be
either a Callable, in which case it will be called with the value C<0>, or
anything else that can be converted to a number, in which case it will use
that as the number of elements in the output C<Seq>.

    say <a b c d e>.tail( { $_ - 2 } ); # OUTPUT: «(c d e)␤»

=head2 routine categorize

Defined as:

    multi method categorize()
    multi method categorize(Whatever)
    multi method categorize($test, :$into!, :&as)
    multi method categorize($test, :&as)
    multi sub categorize($test, +items, :$into!, *%named )
    multi sub categorize($test, +items, *%named )

These methods are directly inherited from C<Any>; see
L<C<Any.list>|/routine/categorize#(Any)_method_categorize> for more examples.

This routine transforms a list of values into a hash representing the
categorizations of those values according to C<$test>, which is called once for
every element in the list; each hash key represents one possible categorization
for one or more of the incoming list values, and the corresponding hash value
contains an array of those list values categorized by the C<$test>, acting like
a mapper, into the category of the associated key.

Note that, unlike L<classify|/routine/classify>, which assumes that the return
value of the mapper is a single value, C<categorize> always assumes that the
return value of the mapper is a list of categories that are appropriate to the
current value.

Example:

    sub mapper(Int $i) returns List {
        $i %% 2 ?? 'even' !! 'odd',
        $i.is-prime ?? 'prime' !! 'not prime'
    }
    say categorize &mapper, (1, 7, 6, 3, 2);
    # OUTPUT: «{even => [6 2], not prime => [1 6], odd => [1 7 3], prime => [7 3 2]}␤»

=head2 routine classify

Defined as:

    multi method classify($test, :$into!, :&as)
    multi method classify($test, :&as)
    multi sub classify($test, +items, :$into!, *%named )
    multi sub classify($test, +items, *%named )

Transforms a list of values into a hash representing the classification
of those values; each hash key represents the classification for one or
more of the incoming list values, and the corresponding hash value
contains an array of those list values classified into the category of
the associated key. C<$test> will be an expression that will produce the
hash keys according to which the elements are going to be classified.

Example:

    say classify { $_ %% 2 ?? 'even' !! 'odd' }, (1, 7, 6, 3, 2);
    # OUTPUT: «{even => [6 2], odd => [1 7 3]}␤»
    say ('hello', 1, 22/7, 42, 'world').classify: { .Str.chars };
    # OUTPUT: «{1 => [1], 2 => [42], 5 => [hello world], 8 => [3.142857]}␤»

It can also take C<:as> as a named parameter, transforming the value
before classifying it:

    say <Innie Minnie Moe>.classify( { $_.chars }, :as{ lc $_ });
    # OUTPUT: «{3 => [moe], 5 => [innie], 6 => [minnie]}␤»

This code is classifying by number of characters, which is the
expression that has been passed as C<$test> parameter, but the C<:as>
block lowercases it before doing the transformation. The named parameter
C<:into> can also be used to classify I<into> a newly defined variable:

    <Innie Minnie Moe>.classify( { $_.chars }, :as{ lc $_ }, :into( my %words{Int} ) );
    say %words; # OUTPUT: «{3 => [moe], 5 => [innie], 6 => [minnie]}␤»

We are declaring the scope of C<%words{Int}> on the fly, with keys that
are actually integers; it gets created with the result of the
classification.

=head2 method Bool

Defined as:

    method Bool(List:D: --> Bool:D)

Returns C<True> if the list has at least one element, and C<False>
for the empty list.

    say ().Bool;  # OUTPUT: «False␤»
    say (1).Bool; # OUTPUT: «True␤»

=head2 method Str

Defined as:

    method Str(List:D: --> Str:D)

Stringifies the elements of the list and joins them with spaces
(same as C<.join(' ')>).

    say (1,2,3,4,5).Str; # OUTPUT: «1 2 3 4 5␤»

=head2 method Int

Defined as:

    method Int(List:D: --> Int:D)

Returns the number of elements in the list (same as C<.elems>).

    say (1,2,3,4,5).Int; # OUTPUT: «5␤»

=head2 method Numeric

Defined as:

    method Numeric(List:D: --> Int:D)

Returns the number of elements in the list (same as C<.elems>).

    say (1,2,3,4,5).Numeric; # OUTPUT: «5␤»

=head2 method Capture

Defined as:

    method Capture(List:D: --> Capture:D)

Returns a L<Capture|/type/Capture> where each L<Pair|/type/Pair>, if any, in the
C<List> has been converted to a named argument (with the
L<key|/type/Pair#method_key> of the L<Pair|/type/Pair> stringified). All other
elements in the C<List> are converted to positional arguments in the order they
are found, i.e. the first non pair item in the list becomes the first positional
argument, which gets index C<0>, the second non pair item becomes the second
positional argument, getting index C<1> etc.

    my $list = (7, 5, a => 2, b => 17);
    my $capture = $list.Capture;
    say $capture.keys;                                # OUTPUT: «(0 1 a b)␤»
    my-sub(|$capture);                                # OUTPUT: «7, 5, 2, 17»

    sub my-sub($first, $second, :$a, :$b) {
        say "$first, $second, $a, $b"
    }

A more advanced example demonstrating the returned C<Capture> being matched
against a L<Signature|/type/Signature>.

    my $list = (7, 5, a => 2, b => 17);
    say so $list.Capture ~~ :($ where * == 7,$,:$a,:$b); # OUTPUT: «True␤»

    $list = (8, 5, a => 2, b => 17);
    say so $list.Capture ~~ :($ where * == 7,$,:$a,:$b); # OUTPUT: «False␤»

=head2 routine pick

Defined as:

    multi sub    pick($count, *@list --> Seq:D)
    multi method pick(List:D: $count --> Seq:D)
    multi method pick(List:D: --> Mu)

If C<$count> is supplied: Returns C<$count> elements chosen at random
and without repetition from the invocant. If C<*> is passed as C<$count>,
or C<$count> is greater than or equal to the size of the list, then all
elements from the invocant list are returned in a random sequence; i.e. they
are returned shuffled.

In I<method> form, if C<$count> is omitted: Returns a single random item from
the list, or Nil if the list is empty

Examples:

    say <a b c d e>.pick;           # OUTPUT: «b␤»
    say <a b c d e>.pick: 3;        # OUTPUT: «(c a e)␤»
    say <a b c d e>.pick: *;        # OUTPUT: «(e d a b c)␤»

=head2 routine roll

Defined as:

    multi sub    roll($count, *@list --> Seq:D)
    multi method roll(List:D: $count --> Seq:D)
    multi method roll(List:D: --> Mu)

If C<$count> is supplied: Returns a sequence of C<$count> elements, each
randomly selected from the list. Each random choice is made independently, like
a separate die roll where each die face is a list element. If C<*> is passed as
C<$count> returns a lazy, infinite sequence of randomly chosen elements from the
original list.

If C<$count> is omitted: Returns a single random item from the list, or
Nil if the list is empty

Examples:

    say <a b c d e>.roll;       # 1 random letter
    say <a b c d e>.roll: 3;    # 3 random letters
    say roll 8, <a b c d e>;    # 8 random letters

    my $random-digits := (^10).roll(*);
    say $random-digits[^15];    # 15 random digits

=head2 routine eager

Defined as:

    multi method eager(List:D: --> List:D)

Evaluates all elements in the C<List> eagerly, and returns them as a C<List>.

    my  \ll = (lazy 1..5).cache;

    say ll[];     # OUTPUT: «(...)␤»
    say ll.eager  # OUTPUT: «(1 2 3 4 5)␤»

=head2 routine reverse

Defined as:

    multi sub    reverse(*@list  --> Seq:D)
    multi method reverse(List:D: --> Seq:D)

Returns a L«C<Seq>|/type/Seq» with the same elements in reverse order.

Note that C<reverse> always refers to reversing elements of a list;
to reverse the characters in a string, use L<flip|/routine/flip>.

Examples:

    say <hello world!>.reverse;     # OUTPUT: «(world! hello)␤»
    say reverse ^10;                # OUTPUT: «(9 8 7 6 5 4 3 2 1 0)␤»

=head2 routine rotate

Defined as:

    multi sub    rotate(@list,  Int:D $n = 1 --> Seq:D)
    multi method rotate(List:D: Int:D $n = 1 --> Seq:D)

Returns a L«C<Seq>|/type/Seq» with the list elements rotated to the left
when C<$n> is positive or to the right otherwise.

Examples:

    say <a b c d e>.rotate(2);   # OUTPUT: (c d e a b)
    say <a b c d e>.rotate(-1);  # OUTPUT: (e a b c d)

B<Note>: Before Rakudo version 2020.06 a new C<List> was returned instead
of a C<Seq>.

=head2 routine sort

Defined as:

    multi sub    sort(*@elems      --> Seq:D)
    multi sub    sort(&custom-routine-to-use, *@elems --> Seq:D)
    multi method sort(List:D:      --> Seq:D)
    multi method sort(List:D: &custom-routine-to-use  --> Seq:D)

Sorts the list, smallest element first. By default
L«C<< infix:<cmp> >>|/routine/cmp» is used for comparing list elements.

If C<&custom-routine-to-use> is provided, and it accepts two arguments,
it is invoked for pairs of list elements, and should return
C<Order::Less>, C<Order::Same> or C<Order::More>.

If C<&custom-routine-to-use> accepts only one argument, the list
elements are sorted according to C<< custom-routine-to-use($a) cmp
custom-routine-to-use($b) >>. The return values of
C<&custom-routine-to-use> are cached, so that C<&custom-routine-to-use>
is only called once per list element.

Examples:

    say (3, -4, 7, -1, 2, 0).sort;                  # OUTPUT: «(-4 -1 0 2 3 7)␤»
    say (3, -4, 7, -1, 2, 0).sort: *.abs;           # OUTPUT: «(0 -1 2 3 -4 7)␤»
    say (3, -4, 7, -1, 2, 0).sort: { $^b leg $^a }; # OUTPUT: «(7 3 2 0 -4 -1)␤»

Additionally, if C<&custom-routine-to-use> returns a C<List>, elements
will be sorted based upon multiple values with subsequent values in the
C<List> being used to break the tie if the comparison between the prior
elements evaluate to C<Order::Same>.

    my @resistance = (
        %( first-name => 'Kyle',  last-name => 'Reese'  ),
        %( first-name => 'Sarah', last-name => 'Connor' ),
        %( first-name => 'John',  last-name => 'Connor' ),
    );
    .say for @resistance.sort: { .<last-name>, .<first-name> };

    #`(
    OUTPUT:
      {first-name => John, last-name => Connor}
      {first-name => Sarah, last-name => Connor}
      {first-name => Kyle, last-name => Reese}
    )

This sorting can be based on characteristics of a single element:

=begin code
say <ddd aaa bbb bb ccc c>.sort( {.chars, .Str} );
# OUTPUT: «(c bb aaa bbb ccc ddd)␤»
=end code

In this case, elements of the array are sorted in ascending order
according first to the string length (C<.chars>) and second to the
actual alphabetical order C<.Str>) if the length is exactly the same.

Any number of criteria can be used in this:
=begin code
say <01 11 111 2 20 02>.sort( { .Int, .comb.sum, .Str } );
# OUTPUT: «(01 02 2 11 20 111)␤»
=end code

=head2 routine reduce

Defined as:

    multi method reduce(Any:D: &with)
    multi sub reduce (&with, +list)

Returns a single "combined" value from a list of arbitrarily many values, by
iteratively applying a routine which knows how to combine I<two> values. In
addition to the subroutine and the list, an initial value can be provided to
initialize the reduction, which ends up being the return value if the list is
empty. Thus C<reduce f, init, list> combines the elements of the list from left
to right, as is shown in the following pseudocode:

=for code :skip-test<Pseudocode>
result0 = init
result1 = f(result0, list[0])
result2 = f(result1, list[1])
...
resultn = f(resultn-1, list[n-1])

C<resultn> is the final result for an n-element list.

    say reduce &infix:<+>, (1, 2, 3); # OUTPUT: «6␤»
    say (1, 2, 3).reduce: &infix:<+>; # OUTPUT: «6␤»
    say reduce &max, (5, 9, 12, 1);   # OUTPUT: «12␤»

If C<list> contains just a single element, the operator is applied to that
single element if possible; if not, it returns the element itself.

    say reduce &infix:<->, (10,);     # OUTPUT: «10␤»

When the list contains no elements, an exception is thrown, unless C<&with>
is an I<operator> with a known identity value (e.g., the identity value of
C«infix:<+>» is 0). For this reason, you're advised to prefix the input list
with an initial value (or explicit identity value):

    my \strings = "One good string!", "And one another good string!";
    say reduce { $^a ~ $^b }, '', |strings;               # like strings.join

    my \numbers = 1, 2, 3, 4, 5;
    say reduce { $^a > $^b ?? $^a !! $^b }, 0, |numbers; # like numbers.max

    sub count-and-sum-evens( (Int \count, Int \sum), Int \x ) {
        x %% 2 ?? (count+1, sum+x) !! (count, sum)
    }

    say reduce &count-and-sum-evens, (0, 0), |numbers;    # OUTPUT: «(2 6)␤»

In the last example, since C<reduce> only supports one initial value we use a
C<List> with two values, which is by itself a single value. The
C<count-and-sum-evens> subroutine takes two positional values: a
C<List> of two C<Int>s and an C<Int>, and return a C<List> storing the count
and sum of the even integers accumulated.

If C<&with> is the code object of an I<operator>, its
inherent identity value and associativity is respected - in other words,
C<(VAL1, VAL2, VAL3).reduce(&infix:<OP>)> is the same as C<VAL1 OP VAL2 OP VAL3>
even for operators which aren't left-associative:

    # Raise 2 to the 81st power, because 3 to the 4th power is 81
    (2,3,4).reduce(&infix:<**>).lsb.say;  # OUTPUT: «81␤»
    (2**(3**4)).lsb.say;                  # OUTPUT: «81␤»
    (2**3**4).lsb.say;                    # OUTPUT: «81␤»

    # Subtract 4 from -1, because 2 minus 3 is -1
    (2,3,4).reduce(&infix:<->).say;       # OUTPUT: «-5␤»
    ((2-3)-4).say;                        # OUTPUT: «-5␤»
    (2-3-4).say;                          # OUTPUT: «-5␤»

Since reducing with an infix operator is a common thing to do, the
L<reduction metaoperator|/language/operators#Reduction_metaoperators> C<[ ]>
provides a syntactic shortcut. Thus, instead of passing the operator's code
object to C<reduce>, just pass the operator directly to C<[ ]>. To use a
user-defined subroutine instead, provide an additional layer of square brackets
around the subroutine's code object:

    say [*] (1, 2, 3, 4);       # OUTPUT: «24␤»
    say [min] (4, 2, 1, 3);     # OUTPUT: «1␤»

    sub mult { $^a * $^b };
    say [[&mult]] (1, 2, 3, 4); # OUTPUT: «24␤»

Semantically, all the following do the same thing:

    my \numbers = 1, 2, 3, 4, 5;
    say reduce { $^a + $^b }, 0, |numbers;
    say reduce * + *, 0, |numbers;
    say reduce &[+], numbers; # operator does not need explicit identity value
    say [+] numbers;

Since C<reduce> is an implicit loop that iterates over with its I<reducing> subroutine,
it responds to C<next>, C<last> and C<redo> statements inside C<&with>:

    sub last-after-seven { last if $^a > 7; $^a + $^b };
    say (2, 3, 4, 5).reduce: &last-after-seven; # OUTPUT: «9␤»

Whether C<reduce> accumulates the elements starting from the left or from the right
depends on the operator. In the functional programming world, this operation is
generally called a L<fold|https://en.wikipedia.org/wiki/Fold_%28higher-order_function%29#Folds_on_lists>.
With a right-associative operator it is a I<right fold>, otherwise (and usually)
it is a I<left fold>. In Raku, you can specify the associativity of an operator
with the L<C«is assoc»|/language/functions#index-entry-is_assoc_(trait)>.

    sub infix:<foo>($a, $b) is assoc<right> { "($a, $b)" }
    say [foo] 1, 2, 3, 4; # OUTPUT: «(1, (2, (3, 4)))␤»

    sub infix:<bar>($a, $b) is assoc<left> { "($a, $b)" }
    say [bar] 1, 2, 3, 4; # OUTPUT: «(((1, 2), 3), 4)␤»

B<Practical example 1:> In this example, we generate a random-ish math
formula (e.g., "(4 + ((3 * x) + 11) / 6))") using C<reduce>.

    my @ops = [Z] (<+ - * />, 1..20)».roll(4);

    say ('x', |@ops).reduce: -> $formula, [$op, $number] {
        Bool.pick ?? "($formula $op $number)"
                  !! "($number $op $formula)"
    }

B<Practical example 2:> Suppose we have a polynomial represented as a list of
integer coefficients, c[n-1], c[n-2], ..., c[0], where c[i] is the coefficient
of xi. We can evaluate it using C<map> and C<reduce> as follows:

    sub evaluate(List:D \c where c.all ~~ Int, Rat:D \x --> Rat:D) {
        my \xi = (c.elems ^... 0).map: -> \i { x ** i }; # [x^(n-1), ..., x^0]
        my \axi = [+] c Z* xi;                           # [c[n-1]*x^(n-1), ..., c[*]x^0]
        [+] axi;                                         # sum of axi
    }

    my \c = 2, 3, 1;       # 2x² + 3x + 1
    say evaluate c, 3.0;   # OUTPUT: «28␤»
    say evaluate c, 10.0;  # OUTPUT: «231␤»

=head2 routine produce

Defined as:

    multi sub    produce(&with, *@values)
    multi method produce(List:D: &with)

Generates a list of all intermediate "combined" values along with the final
result by iteratively applying a function which knows how to combine I<two>
values.

If C<@values> contains just a single element, a list containing that element
is returned immediately. If it contains no elements, an exception is thrown,
unless C<&with> is an I<operator> with a known identity value.

If C<&with> is the function object of an I<operator>, its
inherent identity value and associativity is respected - in other words,
C<(VAL1, VAL2, VAL3).produce(&[OP])> is the same as C<VAL1 OP VAL2 OP VAL3> even
for operators which aren't left-associative:

    # Raise 2 to the 81st power, because 3 to the 4th power is 81
    [2,3,4].produce(&[**]).say;        # OUTPUT: «(4 81 2417851639229258349412352)␤»
    say produce &[**], (2,3,4);        # OUTPUT: «(4 81 2417851639229258349412352)␤»
    say [\**] (2,3,4);                 # OUTPUT: «(4 81 2417851639229258349412352)␤»

    # Subtract 4 from -1, because 2 minus 3 is -1
    [2,3,4].produce(&[-]).say;         # OUTPUT: «(2 -1 -5)␤»
    say produce &[-], (2,3,4);         # OUTPUT: «(2 -1 -5)␤»
    say [\-] (2,3,4);                  # OUTPUT: «(2 -1 -5)␤»

A triangle metaoperator C<[\ ]> provides a syntactic shortcut for
producing with an infix operator:

    # The following all do the same thing...
    my @numbers = (1,2,3,4,5);
    say produce { $^a + $^b }, @numbers;
    say produce * + *, @numbers;
    say produce &[+], @numbers; # operator does not need explicit identity
    say [\+] @numbers;          # most people write it this way

The visual picture of a triangle C<[\> is not accidental. To produce a
triangular list of lists, you can use a "triangular comma":

    [\,] 1..5;
    # (
    # (1)
    # (1 2)
    # (1 2 3)
    # (1 2 3 4)
    # (1 2 3 4 5)
    # )

Since C<produce> is an implicit loop, it responds to C<next>, C<last> and
C<redo> statements inside C<&with>:

    say (2,3,4,5).produce: { last if $^a > 7; $^a + $^b }; # OUTPUT: «(2 5 9)␤»

=head2 routine combinations

Defined as:

    multi sub    combinations($from, $of = 0..*             --> Seq:D)
    multi method combinations(List:D: Int() $of             --> Seq:D)
    multi method combinations(List:D: Iterable:D $of = 0..* --> Seq:D)

Returns a L<Seq|/type/Seq> with all C<$of>-combinations of the invocant list.
C<$of> can be a numeric L<Range|/type/Range>, in which case combinations of the
range of item numbers it represents will be returned (i.e. C<2.6 .. 4> will
return 2-, 3-, and 4-item combinations). Otherwise, C<$of> is coerced to an
L<Int|/type/Int>.

    .say for <a b c>.combinations: 2;
    # OUTPUT:
    # (a b)
    # (a c)
    # (b c)

Above, there are three possible ways to combine the 2-items lists from the
original list, which is what we receive in the output. See
L<permutations|/routine/permutations> if you want permutations instead of
combinations.

With L<Range|/type/Range> argument, we get both three 2-item combinations and
one 3-item combination:

    .say for <a b c>.combinations: 2..3;
    # OUTPUT:
    # (a b)
    # (a c)
    # (b c)
    # (a b c)

If C<$of> is negative or is larger than there are items in the given list, an
empty list will be returned. If C<$of> is zero, a 1-item list containing an
empty list will be returned (there's exactly 1 way to pick no items).

The subroutine form is equivalent to the method form called on the first
argument (C<$from>), with the exception that if C<$from> is not an
L<Iterable|/type/Iterable>, it gets coerced to an C<Int> and combinations are
made from a L<Range|/type/Range> constructed with C<0..^$from> instead:

    .say for combinations 3, 2
    # OUTPUT:
    # (0 1)
    # (0 2)
    # (1 2)

B<Note:> some implementations may limit the maximum value of
non-L<Iterable|/type/Iterable> C<$from>. On Rakudo, 64-bit systems have a limit
of C<2³¹-1> and 32-bit systems have a limit of C<2²⁸-1>.

=head2 routine permutations

Defined as:

    multi sub    permutations(Int()    $from --> Seq:D)
    multi sub    permutations(Iterable $from --> Seq:D)
    multi method permutations(List:D:        --> Seq:D)

Returns all possible permutations of a list as a L<Seq|/type/Seq> of lists:

    .say for <a b c>.permutations;
    # OUTPUT:
    # (a b c)
    # (a c b)
    # (b a c)
    # (b c a)
    # (c a b)
    # (c b a)

C<permutations> treats all elements as unique, thus C<(1, 1, 2).permutations>
returns a list of 6 elements, even though there are only three distinct
permutations, due to first two elements being the same.

The subroutine form behaves the same as the method form, computing permutations
from its first argument C<$from>. If C<$from> is not an
L<Iterable|/type/Iterable>, coerces C<$from> to an C<Int> and picks from a
L<Range|/type/Range> constructed with C<0..^$from>:

    .say for permutations 3;
    # OUTPUT:
    # (0 1 2)
    # (0 2 1)
    # (1 0 2)
    # (1 2 0)
    # (2 0 1)
    # (2 1 0)

=head2 method rotor

Defined as:

    method rotor(*@cycle, Bool() :$partial --> Seq:D)

Returns a sequence of lists, where each sublist is made up of elements of the
invocant.

In the simplest case, C<@cycle> contains just one integer, in which case the
invocant list is split into sublists with as many elements as the integer
specifies. If C<:$partial> is True, the final chunk is included even if it
doesn't satisfy the length requirement:

    say ('a'..'h').rotor(3).join('|');              # OUTPUT: «a b c|d e f␤»
    say ('a'..'h').rotor(3, :partial).join('|');    # OUTPUT: «a b c|d e f|g h␤»

If the element of C<@cycle> is a L<Pair|/type/Pair> instead, the key of the
pair specifies the length of the return sublist, and the value the gap between
sublists; negative gaps produce overlap:

    say ('a'..'h').rotor(2 => 1).join('|');         # OUTPUT: «a b|d e|g h␤»
    say ('a'..'h').rotor(3 => -1).join('|');        # OUTPUT: «a b c|c d e|e f g␤»

If C<@cycle> contains more than element, C<rotor> cycles through it to find
the number of elements for each sublist:

    say ('a'..'h').rotor(2, 3).join('|');           # OUTPUT: «a b|c d e|f g␤»
    say ('a'..'h').rotor(1 => 1, 3).join('|');      # OUTPUT: «a|c d e|f␤»

Combining multiple cycles and C<:partial> also works:

    say ('a'..'h').rotor(1 => 1, 3 => -1, :partial).join('|');
    # OUTPUT: «a|c d e|e|g h␤»

See L<this blog post for more elaboration on rotor|http://blogs.perl.org/users/zoffix_znet/2016/01/perl-6-rotor-the-king-of-list-manipulation.html>.

=head2 method batch

Defined As:

    multi method batch(Int:D $batch --> Seq)
    multi method batch(Int:D :$elems --> Seq)

Returns a sequence of lists, wherein each list with the exception of the last
one is guaranteed to comprise a number of elements equal to the batch size
specified by C<$batch> or C<$elems>, respectively. If the invocant has a number
of elements that is not an integer multiple of the batch size, the last list in
the returned sequence will contain any remaining elements and thus have less
than C<$batch> or C<$elems> elements. Accordingly, C<.batch($batch)> is
shorthand for C<.rotor($batch, :partial)>.

=head2 routine cross

    sub cross(+@e, :&with --> Seq:D)

Computes the cross-product of two or more lists or L<iterables|/type/Iterable>.
This returns a sequence of lists where the first item in each list is an item
from the first iterable, the second is from the second given iterable, etc.
Every item will be paired with every other item in all the other lists.

    say cross(<a b c>, <d e f>).map(*.join).join(",")
    # OUTPUT: «ad,ae,af,bd,be,bf,cd,ce,cf␤»

The C<cross> routine has an infix synonym as well, named L«C<X>|/language/operators#infix_X».

    say (<a b c> X <d e f>).map(*.join).join(",")
    # output is the same as the previous example

If the optional C<with> parameter is passed, it is used as a reduction operation
to apply to each of the cross product items.

    say cross([1, 2, 3], [4, 5, 6], :with(&infix:<*>)).join(",");
    # OUTPUT: «4,5,6,8,10,12,12,15,18␤»

The C<X> operator can be combined with another operator as a
metaoperator to perform a reduction as well:

    say ([1, 2, 3] X* [4, 5, 6]).join(",")
    # same output as the previous example

=head2 routine zip

Defined as:

    sub zip(+@e, :&with --> Seq:D)

Builds a 'list of lists', returned as a sequence, from multiple input lists or
other L<iterables|/type/Iterable>.

C<zip> iterates through each of the input lists synchronously, 'Zipping' them
together, so that elements are grouped according to their input list index, in
the order that the lists are provided.

    say zip(<a b c>, <d e f>, <g h i>);
    # OUTPUT: «((a d g) (b e h) (c f i))␤»

C<zip> has an infix synonym, the L«C<Z> operator|/language/operators#infix_Z».

    say <a b c> Z <d e f> Z <g h i>;                   # same output


C<zip> can provide input to a for loop :

    for <a b c> Z <d e f> Z <g h i> -> [$x,$y,$z] {say ($x,$y,$z).join(",")}
    # OUTPUT: «a,d,g␤b,e,h␤c,f,i␤»

, or more succinctly:

    say .join(",") for zip <a b c>, <d e f>, <g h i>;  # same output

Note, that if the input lists have an unequal number of elements, then
C<zip> terminates once the shortest input list is exhausted, and trailing
elements from longer input lists are discarded.

    say <a b c> Z <d e f m n o p> Z <g h i>;
    # ((a d g) (b e h) (c f i))

In cases where data clipping is possible, but undesired, then consider using
L<roundrobin|/routine/roundrobin> instead of C<zip>.

The optional C<with> parameter will additionally reduce the zipped lists. For
example, the following multiplies corresponding elements together to return a
single list of products.

    .say for zip <1 2 3>, [1, 2, 3], (1, 2, 3), :with(&infix:<*>);
    # OUTPUT: «1␤8␤27␤»

The C<Z> form can also be used to perform reduction by implicitly
setting the C<with> parameter with a metaoperator :

    .say for <1 2 3> Z* [1, 2, 3] Z* (1, 2, 3);        # same output

=head2 routine roundrobin

Defined as:

    sub roundrobin(+list-of-lists --> Seq)

Builds a 'list of lists', returned as a sequence, from multiple input lists or
other L<iterables|/type/Iterable>. C<roundrobin> returns an identical result to
that of L<zip|/type/List#routine_zip>, except when the input lists are allowed
to have an unequal number of elements.

    say roundrobin <a b c>, <d e f>, <g h i>;
    # OUTPUT: «((a d g) (b e h) (c f i))␤»

    say .join(",") for roundrobin([1, 2], [2, 3], [3, 4]);
    # OUTPUT: «1,2,3␤2,3,4␤»

C<roundrobin> does not terminate once one or more of the input lists become
exhausted, but proceeds until all elements from all lists have been processed.

    say roundrobin <a b c>, <d e f m n o p>, <g h i j>;
    # OUTPUT: «((a d g) (b e h) (c f i) (m j) (n) (o) (p))␤»

    say .join(",") for roundrobin([1, 2], [2, 3, 57, 77], [3, 4, 102]);
    # OUTPUT: «1,2,3␤2,3,4␤57,102␤77␤»

Therefore no data values are lost due in the 'zipping' operation. A record of
which input list provided which element cannot be gleaned from the resulting
sequence, however.

C<roundrobin> can be useful in combining messy data to the point where a manual
post-processing step can then be undertaken.

=head2 routine sum

Defined as:

    sub    sum($list  )
    method sum(List:D:)

Returns the sum of all elements in the list or 0 if the list is empty.
Throws an exception if an element can not be coerced into Numeric.

    say (1, 3, pi).sum;       # OUTPUT: «7.14159265358979␤»
    say (1, "0xff").sum;      # OUTPUT: «256␤»
    say sum(0b1111, 5);       # OUTPUT: «20␤»

If the list includes a C<Junction>, the result will accordingly be a
C<Junction>:

=for code
say ( 1|2, 3).sum;            # OUTPUT: «any(4, 5)␤»

When called on native integer arrays, it is also possible to specify
a C<:wrap> named parameter.  This will add the values as native integers,
wrapping around if they exceed the size of a native integer.  If you are
sure you will not exceed that value, or if you don't mind, using C<:wrap>
will make the calculation about 20x as fast.

=for code :preamble<my @a>
my int @values = ^1_000_000;
say @a.sum(:wrap);        # OUTPUT: «499999500000␤»

=head2 method fmt

Defined as:

    method fmt($format = '%s', $separator = ' ' --> Str:D)

Returns a string where each element in the list has been formatted according
to C<$format> and where each element is separated by C<$separator>.

For more information about formats strings, see L<sprintf|/routine/sprintf>.

    my @a = 8..11;
    say @a.fmt('%03d', ',');  # OUTPUT: «008,009,010,011␤»

=head2 method from

Assumes the list contains L«C<Match> objects|/type/Match» and returns the
value of C<.from> called on the first element of the list.

    'abcdefg' ~~ /(c)(d)/;
    say $/.list.from;         # OUTPUT: «2␤»

    "abc123def" ~~ m:g/\d/;
    say $/.list.from;         # OUTPUT: «3␤»

=head2 method to

    "abc123def" ~~ m:g/\d/;
    say $/.to; # OUTPUT: «6␤»

Assumes the C<List> contains L«C<Match> objects|/type/Match», such as the
C<$/> variable being a C<List>, when using C<:g> modifier in regexes. Returns the
value of C<.to> called on the last element of the list.

=head2 method sink

Defined as:

     method sink(--> Nil) { }

It does nothing, and returns C<Nil>, as the definition clearly shows.

    sink [1,2,Failure.new("boo!"),"still here"]; # OUTPUT: «»

=head2 method Set

In general, creates a set which has as members elements of the list.

    say <æ ß þ €>.Set;  # OUTPUT: «Set(ß æ þ €)␤»

However, there might be some unexpected changes in case the list includes
non-scalar data structures. For instance, with L<Pair|/type/Pair>s:

    my @a = (:42a, :33b);
    say @a;                # OUTPUT: «[a => 42 b => 33]␤»
    say @a.Set;            # OUTPUT: «Set(a b)␤»

The set will be composed of the C<key>s of the Pair whose corresponding value
is not 0, eliminating all the values. Please check the
L<C<Set> documentation|/type/Set#Creating_Set_objects> for more examples and a
more thorough explanation.

=head1 Operators

=head2 infix C<cmp>

    multi sub infix:<cmp>(List @a, List @b)

Evaluates C<Lists> by comparing element C<@a[$i]> with C<@b[$i]> (for some
C<Int $i>, beginning at 0) and returning C<Order::Less>, C<Order::Same>, or
C<Order::More> depending on if and how the values differ. If the operation
evaluates to C<Order::Same>, C<@a[$i + 1]> is compared with C<@b[$i + 1]>. This
is repeated until one is greater than the other or all elements are exhausted.

If the C<Lists> are of different lengths, at most only C<$n> comparisons will be
made (where C<$n = @a.elems min @b.elems>). If all of those comparisons evaluate
to C<Order::Same>, the final value is selected based upon which C<List> is
longer.

    say (1, 2, 3) cmp (1, 2, 3);   # OUTPUT: «Same␤»
    say (4, 5, 6) cmp (4, 5, 7);   # OUTPUT: «Less␤»
    say (7, 8, 9) cmp (7, 8, 8);   # OUTPUT: «More␤»

    say (1, 2)    cmp (1, 2, 3);   # OUTPUT: «Less␤»
    say (1, 2, 3) cmp (1, 2);      # OUTPUT: «More␤»
    say (9).List  cmp (^10).List;  # OUTPUT: «More␤»

=end pod

# vim: expandtab softtabstop=4 shiftwidth=4 ft=perl6
